using System;
using System.Collections.Generic;
using System.Reflection;
using NUnit.Framework;
using ODX.Core;
using ODX.LazyUnitTester;

namespace Associations
{
    [Table]
    public abstract class Reader : Entity
    {
        public abstract string Name { get; set;}

        //[LinkTable("ReaderBook", ParentColumn = "ReaderID",
        //    ChildColumn = "BookID")]
        public abstract IEntityList<Book> Books{ get; }
    }

    [Table]
    public abstract class Book : Entity
    {
        public abstract string Title { get; set;}

        //[LinkTable("ReaderBook", ParentColumn = "Book",
        //    ChildColumn = "Reader")]
        public abstract IEntityList<Reader> Readers { get; }
    }

    [TestFixture]
    public class C03_Associations_NxM
    {
        [TestBody]
        static void Main()
        {
            Session session = new Session();
            session.RegisterAssembly(Assembly.GetExecutingAssembly());
            session.Prepare();

            Reader john = session.Create<Reader>();
            john.Name = "John";
            Reader jane = session.Create<Reader>();
            jane.Name = "Jane";

            Book csharp = session.Create<Book>();
            csharp.Title = "C# Developer Power Tools";

            Book java = session.Create<Book>();
            java.Title = "Thinking In Java";

            Book sql = session.Create<Book>();
            sql.Title = "The Art of SQL";

            john.Books.Add(csharp, java);
            jane.Books.Add(csharp, sql);

            List<Book> books = new List<Book>(session.All<Book>("Title"));
            books.Sort(Comparison);
            foreach (Book b in books)
            {
                LUT.WriteLine("'{0}' was read by:", b.Title);
                foreach (Reader r in b.Readers)
                    LUT.WriteLine("\t{0}", r.Name);
                LUT.WriteLine();
            }
        }

        private static int Comparison(Book x, Book y)
        {
            return x.Title.CompareTo(y.Title);
        }

        [Test]
        public void Test()
        {
            LUT.Execute(Main);
        }
    }
}
